Skip to content

Conversation

jaredoconnell
Copy link
Collaborator

Summary

This PR ports the new functionality from benchmark run to benchmark from-file, and does so in a way that reuses as much code as practical to have one source of truth.

Details

  • Fixes from-file by making it to use the new output format.
  • Moves code related to the new output formats to separate functions that are called from both benchmark entrypoints.
  • Moves additional chunks of code out of the large benchmark run entrypoint function for modularity.

Test Plan

Run a benchmark with an output of json or yaml, and use from-file to re-import it and export it. You can select any output type supported by benchmark run.

guidellm benchmark from-file ./result.json --output-formats console
guidellm benchmark from-file ./result.yaml --output-formats yaml

Related Issues


  • "I certify that all code in this PR is my own, except as noted below."

Use of AI

  • Includes AI-assisted code completion
  • Includes code generated by an AI application
  • Includes AI-generated tests (NOTE: AI written tests should have a docstring that includes ## WRITTEN BY AI ##)

Copy link
Collaborator

@sjmonson sjmonson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good looks good; nit on organization.

Comment on lines 55 to 142
DataType = (
Iterable[str]
| Iterable[dict[str, Any]]
| Dataset
| DatasetDict
| IterableDataset
| IterableDatasetDict
| str
| Path
)

OutputFormatType = (
tuple[str, ...]
| list[str]
| dict[str, str | dict[str, Any] | GenerativeBenchmarkerOutput]
| None
)


async def initialize_backend(
backend: BackendType | Backend,
target: str,
model: str | None,
backend_kwargs: dict[str, Any] | None,
) -> Backend:
backend = (
Backend.create(
backend, target=target, model=model, **(backend_kwargs or {})
)
if not isinstance(backend, Backend)
else backend
)
await backend.process_startup()
await backend.validate()
return backend


async def resolve_profile(
constraint_inputs: dict[str, int | float],
profile: Profile | str | None,
rate: list[float] | None,
random_seed: int,
constraints: dict[str, ConstraintInitializer | Any],
):
for key, val in constraint_inputs.items():
if val is not None:
constraints[key] = val
if not isinstance(profile, Profile):
if isinstance(profile, str):
profile = Profile.create(
rate_type=profile,
rate=rate,
random_seed=random_seed,
constraints={**constraints},
)
else:
raise ValueError(f"Expected string for profile; got {type(profile)}")

elif constraints:
raise ValueError(
"Constraints must be empty when providing a Profile instance. "
f"Provided constraints: {constraints} ; provided profile: {profile}"
)
return profile

async def resolve_output_formats(
output_formats: OutputFormatType,
output_path: str | Path | None,
) -> dict[str, GenerativeBenchmarkerOutput]:
output_formats = GenerativeBenchmarkerOutput.resolve(
output_formats=(output_formats or {}), output_path=output_path
)
return output_formats

async def finalize_outputs(
report: GenerativeBenchmarksReport,
resolved_output_formats: dict[str, GenerativeBenchmarkerOutput]
):
output_format_results = {}
for key, output in resolved_output_formats.items():
output_result = await output.finalize(report)
output_format_results[key] = output_result
return output_format_results

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets move all of this to a new file (initializers.py maybe); entrypoints.py is kind of our public interface for ABI usage so I think its best only have the front-facing functions in here. Also allows for some type reuse in scenarios.py

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To bring the conversation online: I thought so too, but it appears that Mark would prefer them to be in the same file. To clarify, I added comments.

Copy link
Collaborator

@sjmonson sjmonson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above comment is non-blocking

Signed-off-by: Jared O'Connell <joconnel@redhat.com>
Signed-off-by: Jared O'Connell <joconnel@redhat.com>
Also remove unused import

Signed-off-by: Jared O'Connell <joconnel@redhat.com>
@jaredoconnell jaredoconnell force-pushed the features/refactor-fix-from-file branch from b17f644 to f926e5b Compare September 24, 2025 21:16
@jaredoconnell jaredoconnell merged commit ab5466b into vllm-project:features/refactor/working Sep 24, 2025
8 of 17 checks passed
@jaredoconnell jaredoconnell deleted the features/refactor-fix-from-file branch September 24, 2025 21:31
@markurtz markurtz added this to the v0.4.0 milestone Oct 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants